package com.ra.config.security;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.ra.mapper.RoleMapper;
import com.ra.pojo.dto.ResourceRoleDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;

import javax.annotation.PostConstruct;
import java.util.Collection;
import java.util.List;

/**
 * Author : 今晚几点睡_Ada
 * Date: 2023/3/10
 * Time: 13:27
 * 注:
 */
@Component
public class CustomFilter implements FilterInvocationSecurityMetadataSource {
    @Autowired
    private RoleMapper roleMapper;

    //用户权限列表
    private static List<ResourceRoleDTO> resourceRoleList;


    /**
     * Java中该注解的说明：@PostConstruct该注解被用来修饰一个非静态的void（）方法。被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行，并且只会被服务器执行一次。PostConstruct在构造函数之后执行，init（）方法之前执行。
     *
     * 通常我们会是在Spring框架中使用到@PostConstruct注解 该注解的方法在整个Bean初始化中的执行顺序：
     *
     * Constructor(构造方法) -> @Autowired(依赖注入) -> @PostConstruct(注释的方法)

     */
    //获取资源角色列表
    @PostConstruct
    private void loadResourceRoleList() {
        resourceRoleList = roleMapper.listResourceRoles();
      //  System.out.println("resourceRoleList = " + resourceRoleList);
    }

    //清除列表
    public void clearDataSource() {
        resourceRoleList = null;
    }


    @Override
    public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {
        //如果是空的 那么加载权限
        if (CollectionUtils.isEmpty(resourceRoleList)) {
            this.loadResourceRoleList();
        }
        FilterInvocation fi = (FilterInvocation) o;
        //获取user操作的资源路径和访问方法
        String method = fi.getRequest().getMethod();
        String url = fi.getRequest().getRequestURI();
        AntPathMatcher antPathMatcher = new AntPathMatcher();
        for (ResourceRoleDTO resourceRoleDTO : resourceRoleList) {
            //比较资源路径和访问方法
            //如果资源路径和访问方法一直
            if (antPathMatcher.match(resourceRoleDTO.getUrl(), url) && resourceRoleDTO.getRequestMethod().equals(method)) {
                //获取权限列表
                List<String> roleList = resourceRoleDTO.getRoleList();
                //如果为空 创建并返回
                if (CollectionUtils.isEmpty(roleList)) {
                    return org.springframework.security.access.SecurityConfig.createList("disable");
                }
                return SecurityConfig.createList(roleList.toArray(new String[]{}));
            }
        }
        // resourceRoleList没有数据返回null

        return null;
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return true;
    }
}
